package com.adam.example;

import co.elastic.clients.elasticsearch.ElasticsearchAsyncClient;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;

import java.io.IOException;

public class ElasticsearchClientHolder {

    private static ElasticsearchClientHolder INSTANCE;
    private RestClient restClient;
    private ElasticsearchTransport elasticsearchTransport;
    private ElasticsearchClient elasticsearchClient;
    private ElasticsearchAsyncClient elasticsearchAsyncClient;


    private ElasticsearchClientHolder() {}

    public static ElasticsearchClientHolder getINSTANCE() {
        if(INSTANCE == null) {
            synchronized (ElasticsearchClientHolder.class) {
                if(INSTANCE == null) {
                    INSTANCE = new ElasticsearchClientHolder();
                }
            }
        }
        return INSTANCE;
    }

    public ElasticsearchClient initializeAndGetClient() {
        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(
                "elastic", "elastic"));

        this.restClient = RestClient.builder(
                        new HttpHost("192.168.0.112", 9200))
                .setHttpClientConfigCallback(httpAsyncClientBuilder -> httpAsyncClientBuilder
                        .setDefaultCredentialsProvider(credentialsProvider))
                .build();

        this.elasticsearchTransport = new RestClientTransport(
                restClient, new JacksonJsonpMapper());

        this.elasticsearchClient = new ElasticsearchClient(elasticsearchTransport);
        this.elasticsearchAsyncClient = new ElasticsearchAsyncClient(elasticsearchTransport);
        return this.elasticsearchClient;
    }

    public ElasticsearchAsyncClient getAsyncClient() {
        return this.elasticsearchAsyncClient;
    }

    public void close() {
        try {
            this.elasticsearchTransport.close();
        } catch (IOException e) {
            System.err.println("close elasticsearch transport exception");
            e.printStackTrace();
        }
    }

}
